package com.cls.common.utils;

import com.cls.common.annotation.DecryptField;
import com.cls.common.annotation.EncryptDecryptEntity;
import com.cls.common.annotation.EncryptField;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author weimaomao
 * @date 2021/3/19
 */
public class CryptPojoUtils {
    /**
     * 对象t注解字段加密
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T encrypt(T t) {
        if (isEncryptAndDecrypt(t)) {
            Field[] declaredFields = t.getClass().getDeclaredFields();
            try {
                if (declaredFields != null && declaredFields.length > 0) {
                    for (Field field : declaredFields) {
                        if (field.isAnnotationPresent(EncryptField.class) && field.getType().toString().endsWith("String")) {
                            field.setAccessible(true);
                            String fieldValue = (String) field.get(t);
                            if (StringUtils.isNotEmpty(fieldValue)) {
                                field.set(t, DESUtil.encrypt(fieldValue));
                            }
                            field.setAccessible(false);
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return t;
    }

    /**
     * 加密单独的字符串
     *
     * @param @param  t
     * @param @return
     * @return T
     * @throws
     */
    public static <T> T encryptStr(T t) {
        if (t instanceof String) {
            t = (T) DESUtil.encrypt((String) t);
        }
        return t;
    }

    /**
     * 对含注解字段解密
     *
     * @param t
     * @param <T>
     */
    public static <T> T decrypt(T t) {
        if (isEncryptAndDecrypt(t)) {
            Field[] declaredFields = t.getClass().getDeclaredFields();
            try {
                if (declaredFields != null && declaredFields.length > 0) {
                    for (Field field : declaredFields) {
                        if (field.isAnnotationPresent(DecryptField.class) && field.getType().toString().endsWith("String")) {
                            field.setAccessible(true);
                            String fieldValue = (String) field.get(t);
                            if (StringUtils.isNotEmpty(fieldValue)) {
                                field.set(t, DESUtil.decrypt(fieldValue));
                            }
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return t;
    }

    /**
     * 判断是否需要加密解密的类
     *
     * @param @param  t
     * @param @return
     * @return Boolean
     * @throws
     */
    public static <T> Boolean isEncryptAndDecrypt(T t) {
        Boolean reslut = false;
        if (t != null) {
            Object object = t.getClass().getAnnotation(EncryptDecryptEntity.class);
            if (object != null) {
                reslut = true;
            }
        }
        return reslut;
    }

    /**
     * 加密Map中的字符串
     *
     * @param @param  t
     * @param @return
     * @return T
     * @throws
     */
    public static Object getEncryptMapValue(Object parameter, List<String> declaredFields) {
        Map<String, Object> paramValMap = (Map) parameter;
        //遍历所有要加密的字段
        declaredFields.forEach(field -> {
            //在方法参数中获取，如果没有则不加密
            Object value = paramValMap.get(field);
            if (value != null) {
                paramValMap.put(field, DESUtil.encrypt((String) value));
            }
        });
        return paramValMap;
    }
}
